package com.program.facesigninsystem.service.impl;

import com.program.facesigninsystem.dao.*;
import com.program.facesigninsystem.entity.CourseOrganization;
import com.program.facesigninsystem.entity.Organization;
import com.program.facesigninsystem.entity.SuperiorsOrganization;
import com.program.facesigninsystem.service.IOrganizationService;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class IOrganizationServiceImpl implements IOrganizationService {
    @Autowired
    private IorganizationDao iorganizationDao;
    @Autowired
    private ISuperiorsOrganizationDao iSuperiorsOrganizationDao;
    @Autowired
    private IUserInfoDao iUserInfoDao;
    @Autowired
    private ISignInCourseDao iSignInCourseDao;
    @Autowired
    private ICourseOrganizationDao iCourseOrganizationDao;

    // TODO 假设的枚举类，用于表示星期几
    enum WeekDay {
        MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7);

        private final int value;

        WeekDay(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }


    @Override
    public Boolean addNewOrganization(String oid, String oname, String email, String createtime, String ocode, String phone, String uid) {
        try {
            iorganizationDao.addNewOrganization(oid, oname, email, createtime, ocode, phone, uid);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public Organization selectbyocode(String ocode) {
        return iorganizationDao.selectbyocode(ocode);
    }


    @Override
    public void deletebyoid(String oid) {
        iorganizationDao.deletebyoid(oid);
        iSuperiorsOrganizationDao.deletebyoid(oid);
        iSuperiorsOrganizationDao.deletebysid(oid);
    }

    @Override
    public Boolean applygroup(String oid, String sid, String createtime) {
        try {
            if (iSuperiorsOrganizationDao.selectapplyhistory(oid, sid) == null) {
                iSuperiorsOrganizationDao.addNewSO(oid, sid, 1, createtime);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public Boolean rejectapply(String soid) {
        try {
            iSuperiorsOrganizationDao.updateapplystates3(soid);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public Boolean passapply(String soid) {
        try {
            iSuperiorsOrganizationDao.updateapplystates2(soid);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public Boolean untiebind(String soid) {
        try {
            iSuperiorsOrganizationDao.updateapplystates4(soid);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public List<JSONObject> selectapplyhistory(String oid, int pageSize, int pageNum) {
//        PageHelper.startPage(pageSize, pageNum);
        List<SuperiorsOrganization> superiorsOrganizationList = iSuperiorsOrganizationDao.selectapplyhistory1(oid);
        List<JSONObject> jsonObjectList = new ArrayList<>();
        for (SuperiorsOrganization superiorsOrganization : superiorsOrganizationList) {
            Organization organization = iorganizationDao.selectbyoid(superiorsOrganization.getOid());
            JSONObject activityObject = new JSONObject();
            activityObject.put("application_status", superiorsOrganization.getApplicationstatus());
            activityObject.put("oname", organization.getOname());
            activityObject.put("email", organization.getEmail());
            activityObject.put("createtime", organization.getCreatetime());
            activityObject.put("ocode", organization.getOcode());
            activityObject.put("phone", organization.getPhone());
            activityObject.put("uname", iUserInfoDao.selectUser(organization.getUid()).get("name"));
            activityObject.put("soid", superiorsOrganization.getId());
            jsonObjectList.add(activityObject);
        }
        return jsonObjectList;
    }

    @Override
    public List<Organization> selectorgbyuid(String uid, int pageSize, int pageNum) {
        return iorganizationDao.selectbyuid(uid);
    }

    @Override
    public List<JSONObject> selectbind(String oid, int pageSize, int pageNum) {
//        PageHelper.startPage(pageSize, pageNum);
        List<SuperiorsOrganization> superiorsOrganizationList = iSuperiorsOrganizationDao.selectbind(oid);
        List<JSONObject> jsonObjectList = new ArrayList<>();
        for (SuperiorsOrganization superiorsOrganization : superiorsOrganizationList) {
            Organization organization = iorganizationDao.selectbyoid(superiorsOrganization.getOid());
            JSONObject activityObject = new JSONObject();
            activityObject.put("oid", organization.getOid());
            activityObject.put("application_status", superiorsOrganization.getApplicationstatus());
            activityObject.put("oname", organization.getOname());
            activityObject.put("email", organization.getEmail());
            activityObject.put("createtime", organization.getCreatetime());
            activityObject.put("ocode", organization.getOcode());
            activityObject.put("phone", organization.getPhone());
            activityObject.put("uname", iUserInfoDao.selectUser(organization.getUid()).get("name"));
            activityObject.put("soid", superiorsOrganization.getId());
            jsonObjectList.add(activityObject);
        }
        return jsonObjectList;
    }

//    //包括上下级组织和同级组织
//    @Override
//    public JSONObject buildFullOrgTree(String rootOid) {
//        Organization rootOrg = iorganizationDao.selectbyoid(rootOid);
//        if (rootOrg == null) {
//            log.warn("未找到根组织，oid=" + rootOid);
//            return new JSONObject();
//        }
//
//        JSONObject currentNode = buildOrgJson(rootOrg);
//        currentNode.put("children", buildChildrenRecursive(rootOid, new HashSet<>()));
//
//        // 获取同级节点
//        List<JSONObject> siblings = buildSiblings(rootOid);
//        siblings.add(currentNode);
//
//        // 可选排序（比如按名称）
//        // siblings.sort(Comparator.comparing(o -> o.getString("oname")));
//
//        // 获取上级组织
//        List<SuperiorsOrganization> parents = iSuperiorsOrganizationDao.selectsup(rootOid);
//        if (parents == null || parents.isEmpty()) {
//            // 如果没有上级，就加一个虚拟 Root 节点
//            JSONObject root = new JSONObject();
//            root.put("name", "Root");
//            root.put("children", siblings);
//            return root;
//        }
//
//        SuperiorsOrganization parentLink = parents.get(0);
//        Organization parentOrg = iorganizationDao.selectbyoid(parentLink.getSid());
//        if (parentOrg == null) {
//            JSONObject fallback = new JSONObject();
//            fallback.put("name", "Root");
//            fallback.put("children", siblings);
//            return fallback;
//        }
//
//        JSONObject parentJson = buildOrgJson(parentOrg);
//        parentJson.put("children", siblings);
//
//        return buildParentRecursive(parentOrg.getOid(), parentJson, new HashSet<>());
//    }

    @Override
    public JSONObject buildFullOrgTree(String rootOid) {
        Organization rootOrg = iorganizationDao.selectbyoid(rootOid);
        if (rootOrg == null) {
            log.warn("未找到根组织，oid=" + rootOid);
            return new JSONObject();
        }

        JSONObject currentNode = buildOrgJson(rootOrg);
        currentNode.put("children", buildChildrenRecursive(rootOid, new HashSet<>()));

        JSONArray nodeArray = new JSONArray();
        nodeArray.add(currentNode);

        JSONObject result = new JSONObject();
        result.put("nodes", nodeArray);

        return result;
    }




    private JSONObject buildOrgJson(Organization org) {
        JSONObject obj = new JSONObject();

        if (org == null) {
            log.warn("buildOrgJson 传入了 null 对象");
            return obj;
        }

        obj.put("oid", org.getOid());
        obj.put("oname", org.getOname());
        obj.put("email", org.getEmail());
        obj.put("address", org.getAddress());
        obj.put("createtime", org.getCreatetime());
        obj.put("ocode", org.getOcode());
        obj.put("phone", org.getPhone());

        try {
            Map<String, Object> user = iUserInfoDao.selectUser(org.getUid());
            if (user != null && user.get("name") != null) {
                obj.put("uname", user.get("name"));
            } else {
                obj.put("uname", "");
            }
        } catch (Exception e) {
            log.warn("查询用户信息失败，uid=" + org.getUid() + "，错误信息：" + e.getMessage());
            obj.put("uname", "");
        }

        return obj;
    }

    private List<JSONObject> buildChildrenRecursive(String oid, Set<String> visited) {
        if (visited.contains(oid)) return Collections.emptyList();
        visited.add(oid);

        List<SuperiorsOrganization> childrenLinks = iSuperiorsOrganizationDao.selectbind(oid);
        List<JSONObject> children = new ArrayList<>();

        for (SuperiorsOrganization childLink : childrenLinks) {
            Organization childOrg = iorganizationDao.selectbyoid(childLink.getOid());
            if (childOrg == null) {
                log.warn("未找到下级组织，oid=" + childLink.getOid());
                continue;
            }

            JSONObject childJson = buildOrgJson(childOrg);
            childJson.put("children", buildChildrenRecursive(childOrg.getOid(), visited));
            children.add(childJson);
        }

        return children;
    }

    private JSONObject buildParentRecursive(String oid, JSONObject currentNode, Set<String> visited) {
        if (visited.contains(oid)) return currentNode;
        visited.add(oid);

        List<SuperiorsOrganization> parents = iSuperiorsOrganizationDao.selectsup(oid);
        if (parents == null || parents.isEmpty()) {
            JSONObject root = new JSONObject();
            root.put("name", "Root");
            root.put("children", Collections.singletonList(currentNode));
            return root;
        }

        SuperiorsOrganization parentLink = parents.get(0);
        Organization parentOrg = iorganizationDao.selectbyoid(parentLink.getSid());
        if (parentOrg == null) {
            log.warn("未找到上级组织，sid=" + parentLink.getSid());
            JSONObject fallback = new JSONObject();
            fallback.put("name", "Root");
            fallback.put("children", Collections.singletonList(currentNode));
            return fallback;
        }

        JSONObject parentJson = buildOrgJson(parentOrg);
        parentJson.put("children", Collections.singletonList(currentNode));

        return buildParentRecursive(parentOrg.getOid(), parentJson, visited);
    }

    private List<JSONObject> buildSiblings(String oid) {
        List<JSONObject> siblings = new ArrayList<>();

        // 查询当前节点的所有上级链接（可能多个，但只取第一个作为主上级）
        List<SuperiorsOrganization> parents = iSuperiorsOrganizationDao.selectsup(oid);
        if (parents == null || parents.isEmpty()) {
            return siblings;
        }

        String parentOid = parents.get(0).getSid();
        // 找出该上级下所有绑定的子组织（即同级）
        List<SuperiorsOrganization> siblingLinks = iSuperiorsOrganizationDao.selectbind(parentOid);

        for (SuperiorsOrganization siblingLink : siblingLinks) {
            if (oid.equals(siblingLink.getOid())) continue; // 排除自身
            Organization siblingOrg = iorganizationDao.selectbyoid(siblingLink.getOid());
            if (siblingOrg != null) {
                JSONObject siblingJson = buildOrgJson(siblingOrg);
                siblingJson.put("children", buildChildrenRecursive(siblingOrg.getOid(), new HashSet<>()));
                siblings.add(siblingJson);
            }
        }

        return siblings;
    }



    @Override
    public List<JSONObject> selectsup(String oid, int pageSize, int pageNum) {
        List<SuperiorsOrganization> superiorsOrganizationList = iSuperiorsOrganizationDao.selectsup(oid);
        List<JSONObject> jsonObjectList = new ArrayList<>();
        for (SuperiorsOrganization superiorsOrganization : superiorsOrganizationList) {
            Organization organization = iorganizationDao.selectbyoid(superiorsOrganization.getSid());
            JSONObject activityObject = new JSONObject();
            activityObject.put("oid", organization.getOid());
            activityObject.put("application_status", superiorsOrganization.getApplicationstatus());
            activityObject.put("oname", organization.getOname());
            activityObject.put("email", organization.getEmail());
            activityObject.put("createtime", organization.getCreatetime());
            activityObject.put("ocode", organization.getOcode());
            activityObject.put("phone", organization.getPhone());
            activityObject.put("uname", iUserInfoDao.selectUser(organization.getUid()).get("name"));
            activityObject.put("soid", superiorsOrganization.getId());
            activityObject.put("whethersee", superiorsOrganization.getWhethersee());
            jsonObjectList.add(activityObject);
        }
        return jsonObjectList;
    }

    @Override
    public List<JSONObject> selectbdhistory(String oid, int pageSize, int pageNum) {
        List<SuperiorsOrganization> superiorsOrganizationList = iSuperiorsOrganizationDao.selectbdhistory(oid);
        List<JSONObject> jsonObjectList = new ArrayList<>();
        for (SuperiorsOrganization superiorsOrganization : superiorsOrganizationList) {
            Organization organization = iorganizationDao.selectbyoid(superiorsOrganization.getSid());
            JSONObject activityObject = new JSONObject();
            activityObject.put("oid", organization.getOid());
            activityObject.put("application_status", superiorsOrganization.getApplicationstatus());
            activityObject.put("oname", organization.getOname());
            activityObject.put("email", organization.getEmail());
            activityObject.put("createtime", organization.getCreatetime());
            activityObject.put("ocode", organization.getOcode());
            activityObject.put("phone", organization.getPhone());
            activityObject.put("uname", iUserInfoDao.selectUser(organization.getUid()).get("name"));
            activityObject.put("soid", superiorsOrganization.getId());
            activityObject.put("whethersee", superiorsOrganization.getWhethersee());
            jsonObjectList.add(activityObject);
        }
        return jsonObjectList;
    }

    @Override
    public Boolean updatebyoid(String oid, String oname, String email, String phone) {
        try {
            iorganizationDao.updatebyoid(oid, oname, email, phone);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public List<Organization> selectorgbyoname(String oname, String uid, int pageSize, int pageNum) {
        return iorganizationDao.selectbyoname(oname, uid);
    }


    @Override
    public List<JSONObject> selectbindbyoname(String oid, String oname, int pageSize, int pageNum) {
        List<SuperiorsOrganization> superiorsOrganizationList = iSuperiorsOrganizationDao.selectbindbyoname(oid, oname);
        List<JSONObject> jsonObjectList = new ArrayList<>();
        for (SuperiorsOrganization superiorsOrganization : superiorsOrganizationList) {
            Organization organization = iorganizationDao.selectbyoid(superiorsOrganization.getOid());
            JSONObject activityObject = new JSONObject();
            activityObject.put("oid", organization.getOid());
            activityObject.put("application_status", superiorsOrganization.getApplicationstatus());
            activityObject.put("oname", organization.getOname());
            activityObject.put("email", organization.getEmail());
            activityObject.put("createtime", organization.getCreatetime());
            activityObject.put("ocode", organization.getOcode());
            activityObject.put("phone", organization.getPhone());
            activityObject.put("uname", iUserInfoDao.selectUser(organization.getUid()).get("name"));
            activityObject.put("soid", superiorsOrganization.getId());
            activityObject.put("whethersee", superiorsOrganization.getWhethersee());
            jsonObjectList.add(activityObject);
        }
        return jsonObjectList;
    }

    @Override
    public Boolean selectwethersee(String oid, String sid) {
        try {
            if ("1".equals(iSuperiorsOrganizationDao.selectwhethersee(oid, sid))) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public Boolean updatewhethersee(String oid, String sid, String whethersee) {
        try {
            iSuperiorsOrganizationDao.updatewhethersee(oid, sid, whethersee);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public List<String> selectjunior(String oid) {
        return iSuperiorsOrganizationDao.selectjunior(oid);
    }

    @Override
    public List<String> selectccidfortj(String oid, String year, String semester, String startweek, String endweek, String section) {
        //1.更改mapper文件，能递归获取所有层级的组织oid
        Set<String> oidSet = new HashSet<>(iSuperiorsOrganizationDao.selectjunior(oid));
        oidSet.add(oid); // 将自身加入到Set
        // 使用Set存储ccid，避免重复
        Set<String> ccidSet = new HashSet<>();
        // 将 startweek 和 endweek 转换为星期列表
        List<String> weeks = getWeeksInRange(startweek, endweek);
        //处理周次【全天（null）+早八（1-2）+上午（1-4+3-5）+下午（6-8）+晚上（10-12）】
        //将 section 转换为具体的节次范围
        List<String> sections = getSectionsByDescription(section);

        for (String oid1 : oidSet) {
            List<CourseOrganization> courseOrganizationList = iCourseOrganizationDao.selectbind(oid1);
            for (CourseOrganization courseOrganization : courseOrganizationList) {
                String ccid = courseOrganization.getCcid();
                // TODO 查询signincourse表，获取符合条件的课程
                List<String> ccidList = iSignInCourseDao.selectCcidByConditions(year, semester, weeks, sections);
                for (String courseCcid : ccidList) {
                    if (courseCcid.equals(ccid)) {
                        ccidSet.add(ccid); // 将符合条件的ccid添加到Set中
                    }
                    //ccidSet.add(courseOrganization.getCcid());
                }
            }
        }
        // 返回去重后的ccid列表
        return new ArrayList<>(ccidSet);
    }


    // 辅助方法：根据 section 描述获取节次范围
    private List<String> getSectionsByDescription(String section) {
        List<String> sections = new ArrayList<>();
        if (section == null) {
            sections.add(null);
        } else {
            switch (section) {
                case "早八":
                    sections.add("第1-2节课");
                    break;
                case "上午":
                    sections.add("第1-2节课");
                    sections.add("第1-4节课");
                    sections.add("第3-5节课");
                    break;
                case "下午":
                    sections.add("第6-7节课");
                    sections.add("第6-8节课");
                    break;
                case "晚上":
                    sections.add("第10-11节课");
                    sections.add("第10-12节课");
                    break;
                case"全天":
                    sections.add("第1-2节课");
                    sections.add("第1-2节课");
                    sections.add("第1-4节课");
                    sections.add("第3-5节课");
                    sections.add("第6-7节课");
                    sections.add("第6-8节课");
                    sections.add("第10-11节课");
                    sections.add("第10-12节课");
                    break;
                default:
                    throw new IllegalArgumentException("未知的section描述: " + section);
            }
        }
        return sections;
    }


    private List<String> getWeeksInRange(String startweek, String endweek) {
        List<String> weeks = new ArrayList<>();
        String[] weekOrder = {"周一", "周二", "周三", "周四", "周五", "周六", "周日"};

        // 获取 startweek 和 endweek 在星期列表中的索引
        int startIdx = Arrays.asList(weekOrder).indexOf(startweek);
        int endIdx = Arrays.asList(weekOrder).indexOf(endweek);

        // 如果startIdx或endIdx无效，返回空列表
        if (startIdx == -1 || endIdx == -1) {
            return weeks;
        }

        // 将startweek到endweek之间的所有星期添加到列表
        for (int i = startIdx; i <= endIdx; i++) {
            weeks.add(weekOrder[i]);
        }

        return weeks;
    }



}
